package com.jerome.rmi;

import com.jerome.rmi.constants.RmiConstant;
import com.jerome.rmi.enums.OperatorEnum;
import com.jerome.rmi.enums.ScannerOperatorEnum;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;

/**
 * Calculator Client
 *
 * @author jerome
 * @date 2023/7/28
 */
public class CalculatorClient {
    /**
     * Get shared remote service
     *
     * @param host service host
     * @param port service port
     * @return Return to the remote Service used by the current client alone
     * @author jerome
     * @date 2023/7/29 11:59
     */
    public synchronized static Calculator getSharedRemoteService(String host, int port) throws Exception {
        Registry registry = LocateRegistry.getRegistry(host, port);
        //Get default service
        RemoteDefault remoteService = (RemoteDefault) registry.lookup(RmiConstant.DEFAULT_SERVER_NAME);
        //Register default Calculator service
        String register = remoteService.registerDefault();
        return (Calculator) registry.lookup(register);
    }

    /**
     * Get Exclusive remote service
     *
     * @param host service host
     * @param port service port
     * @return Return to the remote Service used by the current client alone
     * @author jerome
     * @date 2023/7/29 11:59
     */
    public synchronized static Calculator getExclusiveRemoteService(String host, int port) throws Exception {
        Registry registry = LocateRegistry.getRegistry(host, port);
        //Get default service
        RemoteDefault remoteService = (RemoteDefault) registry.lookup(RmiConstant.DEFAULT_SERVER_NAME);
        //Register new Calculator service
        String register = remoteService.registerNew();
        return (Calculator) registry.lookup(register);
    }

    /**
     * client main method
     *
     * @param args main method parameters
     * @author jerome
     * @date 2023/7/29 13:43
     */
    public static void main(String[] args) {
        try {
            Scanner scan = new Scanner(System.in);
            System.out.println("shared:All clients access the same stack on the server.\nexclusive:Clients have their own stack on the server: each client accesses their own stack, rather than the common one");
            System.out.println("Please enter the selection operation:\n1.shared 2: exclusive");
            int in = scan.nextInt();
            Calculator calculator;
            if (in == RmiConstant.NUM_2) {
                //Use Exclusive Remote Service
                calculator = getExclusiveRemoteService(RmiConstant.HOST, RmiConstant.RMI_PORT);
            } else {
                //Using Shared Remote Service
                calculator = getSharedRemoteService(RmiConstant.HOST, RmiConstant.RMI_PORT);
            }
            while (true) {
                System.out.println("----------------------------");
                System.out.println(ScannerOperatorEnum.string());
                in = scan.nextInt();
                ScannerOperatorEnum scannerOperatorEnum = ScannerOperatorEnum.getByCode(in);
                System.out.println("You chose:" + scannerOperatorEnum.getDesc());

                switch (scannerOperatorEnum) {
                    case PUSH_VALUE:
                        System.out.println("Please input:");
                        in = scan.nextInt();
                        calculator.pushValue(in);
                        break;
                    case PUSH_OPERATION:
                        System.out.println("Please input: any one of 1.min, 2.max, 3.lcm, 4.gcd");
                        in = scan.nextInt();
                        OperatorEnum operatorEnum = OperatorEnum.getByCode(in);
                        if (operatorEnum == null) {
                            System.out.println("Invalid operation");
                        }
                        calculator.pushOperation(operatorEnum.getName());
                        break;
                    case POP:
                        try {
                            System.out.println("result:" + calculator.pop());
                        } catch (Exception e) {
                            System.out.println("result:" + e.getMessage());
                        }
                        break;

                    case IS_EMPTY:
                        System.out.println("result:" + calculator.isEmpty());
                        break;
                    case DELAY_POP:
                        try {
                            System.out.println("Please enter the waiting ms:");
                            in = scan.nextInt();
                            System.out.println("result:" + calculator.delayPop(in));
                        } catch (Exception e) {
                            System.out.println("result:" + e.getMessage());
                        }
                        break;
                    default:
                        System.out.println("Invalid operation");
                        break;
                }
            }

        } catch (Exception e) {
            System.err.println("RMI client exception: " + e.toString());
            e.printStackTrace();
        }
    }
}
